/**
 *
 */
package com.jcroke.DACGraph.DAC;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.ws.rs.core.Response;

import org.apache.commons.lang.CharEncoding;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;

import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFactory;
import com.jcroke.DACGraph.PC32Exception;



/**
 * @author davimacm
 *
 */
public class DACClient
{
    public DACClient ( String host, int port )
    {
        _httpc = new DefaultHttpClient ( new ThreadSafeClientConnManager () ) ;
        _httpc4e = new ApacheHttpClient4Executor ( _httpc ) ;

        _sparqlEndpoint = String.format ( "http://%s:%d/api/v1/sparql", host, port ) ;
    }

    public ResultSet sparql ( String sparql )
    {
        String entity = null ;
        int statusCode = -1 ;

        try
        {
            ClientRequest request = getSparqlRequest ( getSparqlURL ( sparql ) ).accept ( "application/sparql-results+json" ) ;
            ClientResponse<?> response = request.get () ;
            statusCode = response.getStatus () ;
            entity = response.getEntity ( String.class ) ;
        }
        catch ( Exception e )
        {
            throw new PC32Exception ( "error executing a sparql query against DAC", e ) ;
        }

        if ( Response.Status.OK.getStatusCode () != statusCode )
            throw new PC32Exception ( String.format ( "unexpected response from DAC%nstatus code: %d%nbody...%n%s", statusCode, null != entity ? entity : "" ) ) ;

        try { return ResultSetFactory.fromJSON ( new ByteArrayInputStream ( entity.getBytes ( CharEncoding.UTF_8 ) ) ) ; }
        catch ( UnsupportedEncodingException e )
        {
            throw new PC32Exception ( "error decoding response from DAC", e ) ;
        }
    }

    public void shutdown ()
    {
        _httpc4e.close () ;
        _httpc.getConnectionManager ().shutdown () ;
    }

    private ClientRequest getSparqlRequest ( String URL )
    {
        return new ClientRequest ( URL, _httpc4e ) ;
    }

    private String getSparqlURL ( String sparql )
    {
        try { return String.format ( "%s?query=%s", _sparqlEndpoint, URLEncoder.encode ( sparql, CharEncoding.UTF_8 ) ) ; }
        catch ( UnsupportedEncodingException e )
        {
            throw new PC32Exception ( "error building sparql query", e ) ;
        }
    }

    private DefaultHttpClient _httpc = null ;
    private ApacheHttpClient4Executor _httpc4e = null ;
    private String _sparqlEndpoint = null ;
}